﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using Caliburn.Micro;
using PurchaseSales.Manage.Model.Entities;
using PurchaseSales.Manage.Services;
using System.ComponentModel;
using ReactiveUI;
using ReactiveUI.Xaml;

namespace PurchaseSales.Manage.ViewModels
{
    public class PurchaseCommodityViewModel : Screen
    {
        private readonly IPurchaseCommodityRepository _repository;
        private readonly ISupplierRepository _supplierRepository;
        private readonly ICommodityRepository _commodityRepository;
        private Supplier _selectedSupplier;
        private double _parchaseCount;
        private string _remark;
        public ReactiveAsyncCommand SelectedSupplierrCommand { get; set; }
        public ReactiveAsyncCommand SelectedCommodityCommand { get; set; }
        public ReactiveCommand AddCommand { get; set; }
        public ReactiveCommand DeletedCommand { get; set; }
        private ObservableAsPropertyHelper<Supplier> _supplier;
        private ObservableAsPropertyHelper<Commodity> _commodity;
        private ReactiveCollection<PurchaseCommodity> _purchaseCommodities;

        public PurchaseCommodityViewModel(IPurchaseCommodityRepository repository, ISupplierRepository supplierRepository, ICommodityRepository commodityRepository)
        {
            _repository = repository;
            _supplierRepository = supplierRepository;
            _commodityRepository = commodityRepository;


            SelectedSupplierrCommand = new ReactiveAsyncCommand();
            var supplierObserver = SelectedSupplierrCommand.RegisterAsyncFunction(o =>
                                                                                           {
                                                                                               var supplier = o as Supplier;
                                                                                               return supplier;
                                                                                           });
            SelectedCommodityCommand = new ReactiveAsyncCommand();
            var commodityObserver = SelectedCommodityCommand.RegisterAsyncFunction(o =>
                                                                                           {
                                                                                               var commodity = o as Commodity;
                                                                                               return commodity;
                                                                                           });

            _supplier = new ObservableAsPropertyHelper<Supplier>(supplierObserver, supplier => { });
            _commodity = new ObservableAsPropertyHelper<Commodity>(commodityObserver, commodity => { });

            var latest = Observable.CombineLatest(supplierObserver, commodityObserver,
                (supplier, commodity) =>
                {
                    return supplier != null && commodity != null;
                }).StartWith(false);

            AddCommand = new ReactiveCommand(latest);
            AddCommand.Subscribe(o =>
                                     {
                                         var purchaseCommodity = new PurchaseCommodity();
                                         purchaseCommodity.Number = Number;
                                         purchaseCommodity.Supplier = _supplier.Value;
                                         purchaseCommodity.Commodity = _commodity.Value;
                                         purchaseCommodity.PurchaseDate = DateTime.Now;
                                         purchaseCommodity.Count = ParchaseCount;
                                         purchaseCommodity.Totalprice = _commodity.Value.PresalePrice * (decimal)ParchaseCount;

                                         _repository.MakePersistent(purchaseCommodity);
                                         _repository.Commit();

                                         PurchaseCommodities.Add(purchaseCommodity);
                                     });

            DeletedCommand = new ReactiveCommand();
            DeletedCommand.Subscribe(o =>
                                         {
                                             var purchaseCommodity = o as PurchaseCommodity;
                                             _repository.MakeTransient(purchaseCommodity);
                                             _repository.Commit();

                                             PurchaseCommodities.Remove(purchaseCommodity);
                                         });
        }

        protected override void OnInitialize()
        {
            var commodities = _repository.GetAllCommodity();
            PurchaseCommodities = commodities.ToObservable().CreateCollection();

            Suppliers = _supplierRepository.GetAll();
            Commodities = _commodityRepository.GetAll();

        }
        public ReactiveCollection<PurchaseCommodity> PurchaseCommodities
        {
            get { return _purchaseCommodities; }
            set { _purchaseCommodities = value; }
        }

        public IList<Supplier> Suppliers { get; set; }
        public IList<Commodity> Commodities { get; set; }

        public Supplier SelectedSupplier
        {
            get { return _selectedSupplier; }
            set { _selectedSupplier = value; NotifyOfPropertyChange(() => SelectedSupplier); }
        }

        public double ParchaseCount
        {
            get { return _parchaseCount; }
            set { _parchaseCount = value; NotifyOfPropertyChange(() => ParchaseCount); }
        }

        private string _number;
        public string Number
        {
            get { return _number; }
            set { _number = value; NotifyOfPropertyChange(() => Number); }
        }

        public string Remark
        {
            get { return _remark; }
            set { _remark = value; NotifyOfPropertyChange(() => Remark); }
        }
    }
}
